package com.example.sonarqube.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.example.sonarqube.SonarQubeClient;
import com.example.sonarqube.SonarQubeClient.Component;
import com.example.sonarqube.SonarQubeClient.Issue;
import com.example.sonarqube.SonarQubeClient.IssueStatistics;
import com.example.sonarqube.SonarQubeClient.Measure;
import com.example.sonarqube.SonarQubeClient.Project;
import com.example.sonarqube.SonarQubeClient.User;

/**
 * SonarQube数据控制器，提供REST API给前端使用
 */
@RestController
@RequestMapping("/api/sonarqube")
public class SonarQubeController {
    
    @Value("${sonarqube.url}")
    private String sonarQubeUrl;
    
    @Value("${sonarqube.token}")
    private String sonarQubeToken;
    
    /**
     * 获取项目列表
     * @return 项目列表
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/projects")
    public List<Map<String, Object>> getProjects() throws IOException, InterruptedException {
        SonarQubeClient client = new SonarQubeClient(sonarQubeUrl, sonarQubeToken);
        List<Project> projects = client.getProjects();
        
        return projects.stream().map(project -> {
            Map<String, Object> result = new HashMap<>();
            result.put("key", project.getKey());
            result.put("name", project.getName());
            return result;
        }).collect(Collectors.toList());
    }
    
    /**
     * 获取项目指标
     * @param projectKey 项目Key
     * @return 项目指标
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/projects/{projectKey}/metrics")
    public Map<String, Object> getProjectMetrics(@PathVariable String projectKey) 
            throws IOException, InterruptedException {
        SonarQubeClient client = new SonarQubeClient(sonarQubeUrl, sonarQubeToken);
        
        // 定义需要获取的指标
        List<String> metricKeys = List.of(
            "ncloc", "coverage", "new_coverage", 
            "bugs", "vulnerabilities", "code_smells", "security_hotspots",
            "blocker_violations", "critical_violations", "major_violations", 
            "minor_violations", "info_violations", "sqale_index"
        );
        
        SonarQubeClient.ProjectMetrics metrics = client.getProjectMetrics(projectKey, metricKeys);
        Component component = metrics.getComponent();
        
        // 转换指标为Map
        Map<String, String> metricMap = new HashMap<>();
        for (Measure measure : component.getMeasures()) {
            metricMap.put(measure.getMetric(), measure.getValue());
        }
        
        // 计算技术债（小时）
        int techDebtMinutes = Integer.parseInt(metricMap.getOrDefault("sqale_index", "0"));
        double techDebtHours = Math.round(techDebtMinutes / 60.0);
        
        // 构建响应数据
        Map<String, Object> result = new HashMap<>();
        result.put("projectKey", component.getKey());
        result.put("projectName", component.getName());
        result.put("totalIssues", Integer.parseInt(metricMap.getOrDefault("bugs", "0")));
        result.put("criticalIssues", 
            Integer.parseInt(metricMap.getOrDefault("blocker_violations", "0")) +
            Integer.parseInt(metricMap.getOrDefault("critical_violations", "0"))
        );
        result.put("techDebt", techDebtHours);
        result.put("coverage", Double.parseDouble(metricMap.getOrDefault("coverage", "0")));
        
        // 添加问题类型分布
        Map<String, Integer> issueTypes = new HashMap<>();
        issueTypes.put("BUG", Integer.parseInt(metricMap.getOrDefault("bugs", "0")));
        issueTypes.put("VULNERABILITY", Integer.parseInt(metricMap.getOrDefault("vulnerabilities", "0")));
        issueTypes.put("CODE_SMELL", Integer.parseInt(metricMap.getOrDefault("code_smells", "0")));
        issueTypes.put("SECURITY_HOTSPOT", Integer.parseInt(metricMap.getOrDefault("security_hotspots", "0")));
        result.put("issueTypes", issueTypes);
        
        // 添加严重程度分布
        Map<String, Integer> severity = new HashMap<>();
        severity.put("BLOCKER", Integer.parseInt(metricMap.getOrDefault("blocker_violations", "0")));
        severity.put("CRITICAL", Integer.parseInt(metricMap.getOrDefault("critical_violations", "0")));
        severity.put("MAJOR", Integer.parseInt(metricMap.getOrDefault("major_violations", "0")));
        severity.put("MINOR", Integer.parseInt(metricMap.getOrDefault("minor_violations", "0")));
        severity.put("INFO", Integer.parseInt(metricMap.getOrDefault("info_violations", "0")));
        result.put("severity", severity);
        
        return result;
    }
    
    /**
     * 获取项目问题列表
     * @param projectKey 项目Key
     * @return 问题列表
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/projects/{projectKey}/issues")
    public List<Map<String, Object>> getProjectIssues(@PathVariable String projectKey) 
            throws IOException, InterruptedException {
        SonarQubeClient client = new SonarQubeClient(sonarQubeUrl, sonarQubeToken);
        List<Issue> issues = client.getProjectIssues(projectKey, 500);
        
        // 获取项目开发者
        List<User> developers = client.getProjectDevelopers(projectKey);
        Map<String, User> developerMap = developers.stream()
            .collect(Collectors.toMap(User::getLogin, user -> user));
        
        // 转换问题列表
        return issues.stream().map(issue -> {
            Map<String, Object> result = new HashMap<>();
            result.put("key", issue.getKey());
            result.put("message", issue.getMessage());
            result.put("severity", issue.getSeverity());
            result.put("type", issue.getType());
            
            // 获取开发者信息
            User developer = developerMap.getOrDefault(issue.getAssignee(), null);
            Map<String, Object> assignee = new HashMap<>();
            assignee.put("login", issue.getAssignee() != null ? issue.getAssignee() : "未分配");
            assignee.put("name", developer != null ? developer.getName() : "未分配");
            assignee.put("avatar", developer != null ? 
                sonarQubeUrl + "/avatar/" + developer.getLogin() : 
                "https://picsum.photos/id/1005/30/30");
            result.put("assignee", assignee);
            
            result.put("component", issue.getComponent());
            result.put("line", issue.getLine() != null ? issue.getLine() : "");
            result.put("creationDate", issue.getCreationDate().split("T")[0]);
            result.put("status", issue.getStatus());
            
            return result;
        }).collect(Collectors.toList());
    }
    
    /**
     * 获取项目问题统计
     * @param projectKey 项目Key
     * @return 问题统计
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/projects/{projectKey}/statistics")
    public Map<String, Object> getProjectStatistics(@PathVariable String projectKey) 
            throws IOException, InterruptedException {
        SonarQubeClient client = new SonarQubeClient(sonarQubeUrl, sonarQubeToken);
        IssueStatistics statistics = client.getIssueStatistics(projectKey);
        
        // 获取项目开发者
        List<User> developers = client.getProjectDevelopers(projectKey);
        Map<String, User> developerMap = developers.stream()
            .collect(Collectors.toMap(User::getLogin, user -> user));
        
        // 构建开发者问题分布
        List<Map<String, Object>> developerIssues = statistics.getDeveloperCount().entrySet().stream()
            .map(entry -> {
                String login = entry.getKey();
                int issueCount = entry.getValue();
                
                User developer = developerMap.getOrDefault(login, null);
                Map<String, Object> result = new HashMap<>();
                result.put("login", login);
                result.put("name", developer != null ? developer.getName() : login);
                result.put("avatar", developer != null ? 
                    sonarQubeUrl + "/avatar/" + developer.getLogin() : 
                    "https://picsum.photos/id/1005/30/30");
                result.put("total", issueCount);
                
                // 计算严重问题数（假设严重问题占20%）
                result.put("critical", (int) Math.round(issueCount * 0.2));
                
                // 计算技术债（假设每个问题1小时）
                result.put("techDebt", issueCount);
                
                return result;
            })
            .collect(Collectors.toList());
        
        // 构建响应
        Map<String, Object> result = new HashMap<>();
        result.put("typeCount", statistics.getTypeCount());
        result.put("severityCount", statistics.getSeverityCount());
        result.put("developerIssues", developerIssues);
        
        return result;
    }
    
    /**
     * 获取项目开发者列表
     * @param projectKey 项目Key
     * @return 开发者列表
     * @throws IOException
     * @throws InterruptedException
     */
    @GetMapping("/projects/{projectKey}/developers")
    public List<Map<String, Object>> getProjectDevelopers(@PathVariable String projectKey) 
            throws IOException, InterruptedException {
        SonarQubeClient client = new SonarQubeClient(sonarQubeUrl, sonarQubeToken);
        List<User> developers = client.getProjectDevelopers(projectKey);
        
        return developers.stream().map(developer -> {
            Map<String, Object> result = new HashMap<>();
            result.put("login", developer.getLogin());
            result.put("name", developer.getName());
            result.put("email", developer.getEmail());
            result.put("avatar", sonarQubeUrl + "/avatar/" + developer.getLogin());
            return result;
        }).collect(Collectors.toList());
    }
}    